package cn.jasonone.jasonfx.factory;
/**
 * 控制器工厂
 * @author Jason
 * @date: 2020-01-23 17:00
 */

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import cn.jasonone.jasonfx.FXMLLoader;
import cn.jasonone.jasonfx.entity.JFXBaseController;
import cn.jasonone.jasonfx.interceptor.ControllerInterceptor;
import cn.jasonone.jasonfx.proxy.Proxy;
import cn.jasonone.jasonfx.util.ClassUtil;
import cn.jasonone.jasonfx.util.ControllerUtil;
import cn.jasonone.jasonfx.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;

/**
 * 控制器工厂
 * 
 * @author Jason
 * @date: 2020-01-23 17:23
 */
@Slf4j
public class ControllerFactory {
	private static final Map<String, JFXBaseController> PROXY_CACHES = new HashMap<>();

	/**
	 * 获得当前已注册的所有控制器对象
	 * 
	 * @return 控制器
	 */
	public static Collection<JFXBaseController> getControllers() {
		return PROXY_CACHES.values();
	}

	/**
	 * 注册控制器拦截器
	 * 
	 * @param controller 需要拦截的控制器,如果为null,则拦截所有控制器
	 * @param type       拦截器类型
	 */
	public static void registerInterceptor(JFXBaseController controller, Class<? extends ControllerInterceptor> type) {
		registerInterceptor(controller, ClassUtil.newInstance(type));
	}

	/**
	 * 注册控制器拦截器
	 * 
	 * @param controller  需要拦截的控制器,如果为null,则拦截所有控制器
	 * @param interceptor 拦截器
	 */
	public static void registerInterceptor(JFXBaseController controller, ControllerInterceptor interceptor) {
		Proxy.registerInterceptor(controller, interceptor);
	}

	/**
	 * 注册控制器
	 * 
	 * @param collections 控制器类列表
	 */
	public static void register(Collection<Class<?>> collections) {
		for (Class<?> controllerType : collections) {
			register(controllerType);
		}
	}

	/**
	 * 注册控制器
	 * 
	 * @param controllerTypes 控制器类
	 */
	public static void register(Class<?> controllerType) {
		if (ControllerUtil.isController(controllerType)) {
			// 得到控制器名称
			String controllerName = ControllerUtil.getControllerName(controllerType);
			// 得到控制器对象
			JFXBaseController controller = (JFXBaseController) BeanFactory.getBean(controllerName, controllerType);
			// 初始化控制器
			controller.init();
			// 创建控制器代理
			Proxy<JFXBaseController> proxy = new Proxy<>(controller);
			JFXBaseController proxyController = proxy.create();
//			Enhancer enhancer = new Enhancer();
//			enhancer.setSuperclass(controllerType);
//			enhancer.setCallback(new Proxy(controller));
//			JFXBaseController proxyController = (JFXBaseController) enhancer.create();
//			ClassUtil.copyFieldValues(controller, proxyController);
			FXMLLoader loader = new FXMLLoader(proxyController.getPath());
			loader.setRoot(proxyController);
			loader.setController(proxyController);
			loader.setBasicController(controller);
			try {
				loader.load();
				// 绑定模型
				ModeFactory.Handle(proxyController);
				log.debug("注册控制器:{}-{}", controllerName, controllerType.getName());
				PROXY_CACHES.put(controllerName, proxyController);
			} catch (IOException e) {
				throw ExceptionUtil.wrapJasonFxException(e);
			}
		}
	}

	/**
	 * 获得控制器对象
	 * 
	 * @param name 控制器名称
	 * @return JFXBaseController
	 */
	public static JFXBaseController getController(String name) {
		return PROXY_CACHES.get(name);
	}

	/**
	 * 获得控制器对象
	 * 
	 * @param type 控制器类
	 * @return JFXBaseController
	 */
	public static JFXBaseController getController(Class<?> type) {
		String controllerName = ControllerUtil.getControllerName(type);
		if (!PROXY_CACHES.containsKey(controllerName)) {
			// 如果不存在则自动注册
			register(type);
		}
		return getController(controllerName);
	}
}
